package node.java;

import com.google.common.base.Joiner;
import utils.Base;
import utils.titles.Title;

import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

/**
 * Created by thormentor on 27-04-2014.
 */
public class JavaClass extends Base {
    private static final DateTimeFormatter FORMATTER = DateTimeFormatter.ofPattern("dd/MM/yyyy");

    private final List<JavaField> fields = new ArrayList<>();
    private final List<JavaMethod> methods = new ArrayList<>();
    private final Map<String, JavaImport> imports = new LinkedHashMap<>();
    private JavaClass superClass;
    private boolean isAbstract;
    private String annotation;

    public JavaClass(Title title) {
        super(Title.PASCAL_CASE, title);
    }

    public void createMethods(Map<String, String> methods){
        for(Map.Entry<String, String> entry : methods.entrySet())
            createMethod(entry.getKey(), entry.getValue());
    }

    public void setAnnotation(String annotation){
        this.annotation = annotation;
        addImport("entity.entity.entity_model.model.annotations.*");
    }

    private void createMethod(String name, String annotation) {
        methods.add(new JavaMethod(this, name, annotation));
    }

    @Override
    public String toString() {
        String signature = Joiner.on(" ").skipNulls().join(
                "public",
                isAbstract ? "abstract" : null,
                "class",
                super.toString(),
                superClass == null ? null : "extends " + superClass.getName()
        );

        return Joiner.on("\n\n").skipNulls().join(
                "package bamp.entity_model;",
                getImports(),
                Joiner.on("\n").skipNulls().join(
                        "/**",
                        " * Created by thormentor on " + LocalDate.now().format(FORMATTER) + ".",
                        " */",
                        annotation,
                        signature + " {",
                        Joiner.on("\n\n").join(fields),
                        Joiner.on("\n\n").join(methods),
                        "}"
                )
        );
    }

    public void createFields(Map<String, String> fields){

    }

    public void createField(Class type, String fieldName, String annotation) {
        createField(type.getPackage().getName(), type.getSimpleName(), fieldName, annotation);
    }

    void addImport(String aClass) {
        if (imports.containsKey(aClass))
            return;

        imports.put(aClass, new JavaImport(aClass));
    }

    public String getImports() {
        return imports.size() == 0 ? null : Joiner.on("\n").join(imports.values());
    }

    public void createField(JavaClass javaClass, String fieldName, String annotation) {
        createField(null, javaClass.getName(), fieldName, annotation);
    }

    public void createField(String aPackage, String type, String fieldName, String annotation) {
        JavaField field = new JavaField(this, type, fieldName, annotation);
        if(aPackage != null && !aPackage.equals(Object.class.getPackage().getName()))
            addImport(aPackage + "." + type);

        fields.add(field);
    }

    public void setSuperClass(JavaClass superClass) {
        this.superClass = superClass;
        superClass.setAbstract();
    }

    public void setAbstract() {
        this.isAbstract = true;
    }
}
